-- Lua Battle System - 事件系统
-- 采用观察者模式设计，支持事件注册、触发和移除

local Logger = require("utils.logger")

local EventSystem = {
    -- 事件监听器映射表
    -- 格式: events[event_name] = {listener1, listener2, ...}
    events = {}
}

-- 事件系统构造函数
function EventSystem:new()
    local o = {}
    setmetatable(o, self)
    self.__index = self
    o:init()
    return o
end

-- 初始化事件系统
function EventSystem:init()
    self.events = {}
    Logger.info("事件系统初始化完成")
end

-- 注册事件监听器
-- @param event_name 事件名称
-- @param listener 监听器函数
-- @param priority 优先级（可选，默认为0，值越大优先级越高）
function EventSystem:register(event_name, listener, priority)
    priority = priority or 0
    
    if not self.events[event_name] then
        self.events[event_name] = {}
    end
    
    -- 检查监听器是否已存在
    for _, registered_listener in ipairs(self.events[event_name]) do
        if registered_listener.func == listener then
            Logger.warn("监听器已注册到事件: " .. event_name)
            return false
        end
    end
    
    -- 添加监听器
    table.insert(self.events[event_name], {
        func = listener,
        priority = priority
    })
    
    -- 按优先级排序（降序）
    table.sort(self.events[event_name], function(a, b) 
        return a.priority > b.priority 
    end)
    
    Logger.debug("监听器注册到事件: " .. event_name)
    return true
end

-- 移除事件监听器
-- @param event_name 事件名称
-- @param listener 监听器函数（可选，不提供则移除该事件的所有监听器）
function EventSystem:unregister(event_name, listener)
    if not self.events[event_name] then
        Logger.warn("事件不存在: " .. event_name)
        return false
    end
    
    -- 如果没有指定监听器，移除该事件的所有监听器
    if not listener then
        self.events[event_name] = nil
        Logger.debug("移除事件的所有监听器: " .. event_name)
        return true
    end
    
    -- 查找并移除指定监听器
    for i, registered_listener in ipairs(self.events[event_name]) do
        if registered_listener.func == listener then
            table.remove(self.events[event_name], i)
            Logger.debug("移除事件监听器: " .. event_name)
            return true
        end
    end
    
    Logger.warn("监听器未注册到事件: " .. event_name)
    return false
end

-- 触发事件
-- @param event_name 事件名称
-- @param ... 事件参数
function EventSystem:trigger(event_name, ...)
    if not self.events[event_name] then
        Logger.debug("触发事件，但没有监听器: " .. event_name)
        return {}
    end
    
    Logger.debug("触发事件: " .. event_name)
    
    -- 存储所有监听器的返回值
    local results = {}
    
    -- 调用所有监听器
    for _, listener in ipairs(self.events[event_name]) do
        local success, result = pcall(listener.func, ...)
        if not success then
            Logger.error("事件监听器执行失败: " .. event_name .. ", 错误: " .. tostring(result))
        else
            table.insert(results, result)
        end
    end
    
    return results
end

-- 检查事件是否有监听器
-- @param event_name 事件名称
-- @return boolean 是否有监听器
function EventSystem:has_listeners(event_name)
    return self.events[event_name] and #self.events[event_name] > 0
end

-- 获取事件的监听器数量
-- @param event_name 事件名称
-- @return number 监听器数量
function EventSystem:get_listener_count(event_name)
    if not self.events[event_name] then
        return 0
    end
    return #self.events[event_name]
end

-- 清除所有事件监听器
function EventSystem:clear_all()
    self.events = {}
    Logger.info("清除所有事件监听器")
end

-- 导出模块
return EventSystem
